package com.movie.ticket.sale.assembly.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.movie.ticket.sale.assembly.config.UpdateUtil;
import com.movie.ticket.sale.assembly.entity.*;
import com.movie.ticket.sale.assembly.mapper.*;

import com.movie.ticket.sale.assembly.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.movie.ticket.sale.moviecommon.common.Result;
import com.movie.ticket.sale.pram.*;


import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Manager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.lang.management.MemoryManagerMXBean;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author muzi
 * @since 2020-12-07
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private CommentDataMapper commentDataMapper;
    @Autowired
    private MovieMapper movieMapper;
    @Autowired
    private OrderMovieMapper orderMovieMapper;
    @Autowired
    private AuditoriumMapper auditoriumMapper;
    @Autowired
    private CinemaMapper cinemaMapper;
    @Autowired
    private PeridMapper peridMapper;
    @Autowired
    private OrderTicketMapper orderTicketMapper;
    @Autowired
    private DiscountMapper discountMapper;
    @Autowired
    private UserVipMapper userVipMapper;
    @Autowired
    private OrderVipMapper orderVipMapper;
    @Autowired
    private VipMapper vipMapper;
    @Autowired
    private ComplainMapper complainMapper;
    @Autowired
    private UpdateUtil updateUtil;
    @Autowired
    private ManagerMapper managerMapper;


    //修改用户的信息
    public int changeUser(UserPram userPram) {
        //动态修改

        //密码校验
        if (userPram.getPassword() != null) {
            if (userPram.getPassword().length() < 5) {
                //密码少于6位 不予修改
                return 0;
            }
            userMapper.changeUsers(userPram);
            //修改manager
            managerMapper.changeManager(userPram);
        }
        userMapper.changeUsers(userPram);
        managerMapper.changeManager(userPram);
        return 1;
    }

    //查询往期评论的方法 图片多张
    public List<CommentPram> findCommentPrams(String tel) {

        //通过电话号码查出该用户的id
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("tel", tel);
        User user1 = userMapper.selectOne(wrapper);
        Integer id = user1.getId();
        //通过id 查询出 所有的评论集合
        QueryWrapper wrapper1 = new QueryWrapper();
        wrapper1.eq("user_id", id);
        List<Comment> list = commentMapper.selectList(wrapper1);
        //存放评论加图片集合的集合
        List<CommentPram> commentPrams = new ArrayList<>();

        //遍历集合 将每条评论的照片集合找出来
        for (int index = 0; index < list.size(); index++) {
            //通过每条评论的id 找出
            Integer id1 = list.get(index).getId();
            QueryWrapper wrapper2 = new QueryWrapper();
            wrapper2.eq("comment_id", id1);
            //获取评论信息的集合
            List<CommentData> list1 = commentDataMapper.selectList(wrapper2);
            //取出图片地址信息集合
            List<String> paths = new ArrayList<>();
            for (CommentData commentData : list1) {
                paths.add(commentData.getPath());
            }
            //取出电影名字
            Integer movieId = list.get(index).getMovieId();
            //通过movieId查询movie 名字
            Movie movie = movieMapper.selectById(movieId);
            String name = movie.getName();
            //将数据存入对象
            CommentPram commentPram = new CommentPram();
            commentPram.setCommentId(id1);
            commentPram.setComment(list.get(index).getComment());
            commentPram.setPaths(paths);
            commentPram.setDegree(list.get(index).getDegree());
            commentPram.setMovieName(name);
            //将对象存入集合
            commentPrams.add(commentPram);
        }

        return commentPrams;
    }

    //删除一条评论
    public void deleteComment(Integer commentId) {
        //删除评论
        commentMapper.deleteById(commentId);
        //删除图片绑定
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.eq("comment_id", commentId);
        commentDataMapper.delete(wrapper);
    }

    //查询某个用户往期订单的方法
    public IPage<OrderPram> getUserOrders(int currPage, int number, int userId) {
        Page page = new Page(currPage, number);
        IPage<OrderPram> userOrders = userMapper.findUserOrder(page, userId);

        //将订单集合返回
        return userOrders;
    }

    //查询某订单下电影票详情
    public List<?> findTickets(Integer orderId) {
        //电影片对象
        TicketsPram ticketsPram = new TicketsPram();
        //电影票集合
        ArrayList<TicketsPram> ticketsPrams = new ArrayList<>();

        //用订单ID查询查询出订单对象
        OrderMovie orderMovie = orderMovieMapper.selectById(orderId);
        Integer movieId = orderMovie.getMovieId();
        Integer perId = orderMovie.getPeridId();
        //通过场次id查询出开始时间和结束时间
        Perid perid = peridMapper.selectById(perId);
        ticketsPram.setStartTime(perid.getStartTime());
        ticketsPram.setEndTime(perid.getEndTime());
        ticketsPram.setSeatStram(perid.getSeatStram());
        //用订单查出电影名 电影院名 影厅类型 影厅名
        Movie movie = movieMapper.selectById(movieId);
        String name = movie.getName();
        ticketsPram.setMovieName(name);

        Integer cinemaId = orderMovie.getCinemaId();
        Cinema cinema = cinemaMapper.selectById(cinemaId);
        ticketsPram.setCinemaName(cinema.getCinemaName());

        Integer auditoriumId = orderMovie.getAuditoriumId();
        Auditorium auditorium = auditoriumMapper.selectById(auditoriumId);
        ticketsPram.setAuditoriumName(auditorium.getName());
        ticketsPram.setType(auditorium.getType());

        //通过订单Id查询出下面所有票 再放入集合返回
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_movie_id", orderId);
        List<OrderTicket> list = orderTicketMapper.selectList(wrapper);
        //遍历存入对象 添加到集合
        for (OrderTicket orderTicket : list) {
            if (orderTicket.getState() == 1) {
                ticketsPram.setState("正常");
            } else if (orderTicket.getState() == 0) {
                ticketsPram.setState("空闲");
            } else if(orderTicket.getState() == -1){
                ticketsPram.setState("未支付");
            }else if(orderTicket.getState() == -2){
                ticketsPram.setState("支付超时作废");
            }else if(orderTicket.getState() == 2){
                ticketsPram.setState("改签");
            }else if(orderTicket.getState() == 3){
                ticketsPram.setState("部分退票");
            }else if(orderTicket.getState() == 4){
                ticketsPram.setState("全部退票");
            }
            //存放ticketId
            ticketsPram.setId(orderTicket.getId());
            //存入集合
            ticketsPrams.add(ticketsPram);
        }
        return ticketsPrams;
    }
        //改签=================
    public int changeSeat(int orderId, String[] seats, Integer peridId) {
        System.out.println(orderId + "," + seats.length + "," + peridId);
        //从未开始的同一个电影院的 同一个 电影中选 增加次数 只有1次机会
        //通过订单的id 查询该票详情
        //次数大于一  不能改签  查询订单 退了票后不能改签 时间小于电影开始前2小时 不能改签
        OrderMovie orderMovie = orderMovieMapper.selectById(orderId);
        Integer changeTimes = orderMovie.getChangeTimes();
        Integer refund = orderMovie.getRefund();
        Integer perId = orderMovie.getPeridId();
        //查询出该订单下该场次的开场时间
        Perid perid = peridMapper.selectById(perId);
        //查询开始时间
        LocalDateTime startTime = perid.getStartTime();


        String format = "yyyy-MM-dd HH:mm";
        // DateTimeFormatter.ofPattern方法根据指定的格式输出时间
        String formatDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
        LocalDateTime now = LocalDateTime.parse(formatDateTime, DateTimeFormatter.ofPattern(format));

        Duration duration = Duration.between(now, startTime);//时间差值
        long toHours = duration.toHours();//插值 now - startTime
        System.out.println("=============================="+toHours);
        System.out.println(startTime);
        System.out.println(now);

        if (changeTimes >= 1) {
            System.out.println(changeTimes);
            //已改签过一次 不能改签
            return 0;
        } else if (refund >= 1) {
            //进行过退票操作后 不能改签
            return 1;
        } else if (toHours < 2) {
//            时间小于电影开场前2小时 不能改签
            return 2;
        }
        //改签 保存信息
        //将订单改签次数加一
        for(int index=0;index<seats.length;index++){
            orderMovie.setChangeTimes(orderMovie.getChangeTimes()+1);
        }

        //场次用传进来的
        orderMovie.setPeridId(peridId);
        orderMovie.setState(5);//状态为改签

        //改变订单
        orderMovieMapper.updateById(orderMovie);

        //遍历该订单下的所有电影票
        QueryWrapper wrapper1 = new QueryWrapper();
        wrapper1.eq("order_movie_id", orderId);
        List<OrderTicket> list = orderTicketMapper.selectList(wrapper1);

        //修改时间
        LocalDateTime news = LocalDateTime.now();//修改订单的时间
        //改签 遍历电影票集合
        for (int index = 0; index < seats.length; index++) {
            //根据电影票id 改变电影票
            OrderTicket orderTicket = new OrderTicket();
            orderTicket.setCreateTime(news);
            orderTicket.setState(2);//改签状态
            orderTicket.setSeatNumber(seats[index]);
            orderTicket.setId(list.get(index).getId());
            orderTicket.setOrderMovieId(list.get(index).getOrderMovieId());
            //更新
            orderTicketMapper.updateById(orderTicket);
        }

        return 3;

    }

    //新增一条评论
    public void addComment(int userId, int orderId, String comment, MultipartFile[] paths, Double degree) {
        Comment comment1 = new Comment();
        //通过订单id 查询出电影id
        OrderMovie orderMovie = orderMovieMapper.selectById(orderId);
        comment1.setMovieId(orderMovie.getMovieId());
        comment1.setUserId(userId);
        comment1.setComment(comment);
        comment1.setDegree(degree);
        //更新
        commentMapper.insert(comment1);
        int id = comment1.getId();
        //将评论图片 保存
        Result commont = updateUtil.updateFiles("comment", paths, id);
        System.out.println(commont);
        String[] url = (String[]) commont.getData();
        //将地址和保存
        for (int index = 0; index < url.length; index++) {
            CommentData commentData = new CommentData();
            commentData.setCommentId(id);
            commentData.setPath(url[index]);
            //新增
            commentDataMapper.insert(commentData);
        }

        //改变订单评论的状态
        orderMovie.setStatus(1);
        orderMovieMapper.updateById(orderMovie);


    }

    //查询优惠券
    public IPage<Discount> getAllDiscounts(int currPage, int number) {
        //查询的优惠券userId为0 0代表未被兑换
        Page<Discount> page = new Page<>(currPage, number);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id", 0);
        Page discounts = discountMapper.selectPage(page, wrapper);

        return discounts;
    }

    //参加优惠券活动兑换
    public int changeDiscount(int discountId, int userId1) {
        //参加活动 先查看积分 前端不会让其看到别人已经兑换了的优惠券
        Discount discount = discountMapper.selectById(discountId);
        Integer points = discount.getPoints();//需要的积分
        Integer userId = discount.getUserId();
        //查询用户多少积分
        User user = userMapper.selectById(userId1);
        Integer points1 = user.getPoints();
        if (userId != 0) {
            return 0;//已被抢购 兑换失败
        }
        //判断积分是否足够
        if (points1 < points) {
            return 1;//积分不足 继续加油
        }
        //减少积分 绑定该优惠券
        user.setPoints(points1 - points);
        userMapper.updateById(user);
        discount.setUserId(userId1);
        discountMapper.updateById(discount);//绑定该优惠券
        return 2;
    }


    //查看自己往期的优惠券 时间排序
    public IPage<Discount> getDiscount(int currPage, int number, int userId) {
        //调用
        Page<Discount> page = new Page<>(currPage, number);
        IPage<Discount> discounts = discountMapper.findDiscounts(page, userId);
        return discounts;
    }

    //查看自己拥有的vip 状态为1则是
    public List<?> getVip(int currPage, int number, int userId) {
        //通过userId查出vip集合
        UserVipPram userVipPram = new UserVipPram();//定义一个存返回值的对象
        List<UserVipPram> userVipPrams = new ArrayList<>();
//        Page<UserVipPram> page = new Page<>(currPage,number);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id", userId);
        wrapper.eq("state", 1);
        List<UserVip> list = userVipMapper.selectList(wrapper);
        //遍历用cinemaId查出cinema名字
        for (UserVip userVip : list) {
            Cinema cinema = cinemaMapper.selectById(userVip.getCinemaId());
            userVipPram.setCinemaName(cinema.getCinemaName());
            userVipPram.setId(userVip.getId());
            userVipPram.setState("会员");
            userVipPram.setVipEndData(userVip.getVipEndData());
            userVipPram.setUserId(userVip.getUserId());
            //存入集合
            userVipPrams.add(userVipPram);
        }

        return userVipPrams;
    }

    //办理某家影院的会员
    public void buyVip(double price, String tradeNuo, int mouth, int userId, int vipId) {
        log.info("传过来的userId：{}",userId);
        //通过vipId查询出cinemaId
        Vip vip = vipMapper.selectById(vipId);
        Integer cinemaId = vip.getCinemaId();

        //创建一个Vip
        OrderVip orderVip = new OrderVip();
        orderVip.setTradeNuo(tradeNuo);
        orderVip.setUserId(userId);
        orderVip.setCinemaId(cinemaId);
        orderVip.setPrice(price);
        orderVip.setCreateTime(LocalDateTime.now());
        orderVip.setMonth(mouth);
        orderVip.setVipId(vipId);
        orderVip.setState(1);
        //新增订单
        orderVipMapper.insert(orderVip);
        //绑定用户
        UserVip userVip = new UserVip();
        userVip.setUserId(userId);
        userVip.setCinemaId(cinemaId);
        //结束时间 是月份 加上 创建时间
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endDate = now.plusMonths(mouth);
        userVip.setVipEndData(endDate);
        userVip.setState(0);
        userVipMapper.insert(userVip);

    }

    //查看拥有会员影院
    public IPage<CinemaVip> getCinemaVip(int currPage, int number) {
        //查询所有的vip集合
        Page page = new Page(currPage, number);
        IPage<CinemaVip> cinemaVips = userMapper.findCinemaVip(page);
        return cinemaVips;
    }

    //新增影院投诉
    public void addComplain(int orderId, String content, int userId) {
        //由订单查出电影id
        OrderMovie orderMovie = orderMovieMapper.selectById(orderId);
        Integer cinemaId = orderMovie.getCinemaId();
        Complain complain = new Complain();
        complain.setCinemaId(cinemaId);
        complain.setContent(content);
        complain.setUserId(userId);
        complain.setState(1);
        complain.setOrderMovieId(orderId);
        complainMapper.insert(complain);
        //改变订单投诉状态
        orderMovie.setStatu(1);
        orderMovieMapper.updateById(orderMovie);
    }

    //退款
    public int refund(int[] ticketIds) {
        //通过电影票的id查询出订单id
        OrderTicket orderTicket = orderTicketMapper.selectById(ticketIds[0]);
        Integer orderMovieId = orderTicket.getOrderMovieId();
        System.out.println("传入的电影票id"+ticketIds);
        System.out.println("改电影票的订单id:"+orderMovieId);
        //通过订单id查询 订单 如果改过票 那么前端不会显示退票按钮了
        OrderMovie orderMovie = orderMovieMapper.selectById(orderMovieId);
        //判断是否只有这 一张票
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_movie_id", orderMovieId);
        List<OrderTicket> list = orderTicketMapper.selectList(wrapper);
        // 遍历  退过款的电影票没有退款选项 所以传过来的全是可以退款的id
        //退款只能退一次
        if (orderMovie.getRefund() == 0) {
            //可以退
            if (list.size() == 1) {
                orderTicket.setState(3);//只有一张票 为退票
                orderTicketMapper.updateById(orderTicket);
                //修改订单状态 删除场次座位 将钱返回给用户
                orderMovie.setRefund(orderMovie.getRefund() + 1);
                orderMovie.setState(-2);
                orderMovieMapper.updateById(orderMovie);
                //看是否有优惠券 退还
                Integer discountId = orderMovie.getDiscountId();
                //只有一张 全部退票 退钱   支付宝======================
                return 1;
            } else {
                //
                for (int index = 0; index < ticketIds.length; index++) {
                    //将这些票的装态全部改了
                    orderMovie.setRefund(orderMovie.getRefund() + 1);//退票数量
                    OrderTicket orderTicket1 = orderTicketMapper.selectById(ticketIds[index]);
                    orderTicket1.setState(3);
                    orderTicketMapper.updateById(orderTicket1);
                }
                //修改订单状态
                orderMovie.setNumber(ticketIds.length);
                if (list.size() != ticketIds.length) {
                    //部分退票 状态orderMovie为2
                    orderMovie.setState(2);
                    orderMovieMapper.updateById(orderMovie);
                    return 2;
                } else {
                    orderMovie.setState(-2);//全部退票
                    orderMovieMapper.updateById(orderMovie);
                    return 3;
                }
            }
        }
        //不能退 退过一次不能再退
        return 1;

    }


}



